#ifndef _COMPILER_COMPILER_H
#define _COMPILER_COMPILER_H

#include "obj_fn.h"
#define	MAX_LOCAL_VAR_NUM 128
#define MAX_UPVALUE_NUM	128
#define MAX_ID_LEN 128	//变量名最大长度

#define MAX_METHOD_NAME_LEN MAX_ID_LEN
#define MAX_ARG_NUM 16

//函数名长度+'('+n个参数+(n-1)个参数分隔符+')'
#define MAX_SIGN_LEN MAX_METHOD_NAME_LEN + MAX_ARG_NUM * 2 + 1;

#define MAX_FIELD_NUM 128


//upvalue结构
typedef struct{
	//如果此upvalue是直接 外层函数的局部变量就置为true，否则就置为false
	bool isEnclosingLocalVar;

	//外层函数中局部变量的索引或外层函数中upvalue的索引
	//这取决于isEnclosingLocalVar的值
	uint32_t index;
} Upvalue;

//局部变量
typedef struct{
	const char* name;
	uint32_t length;
	int scopeDepth;	//局部变量作用域
	//表示本函数中的局部变量是否是其内层函数所引用的upvalue
	//当其内层函数引用此变量时，由其内层函数来设置此项为true
	bool isUpvalue;
} LocalVar;

//签名
typedef enum{
	SIGN_CONSTRUCT, 		//构造函数
	SIGN_METHOD,			//普通方法
	SIGN_GETTER,			//getter方法
	SIGN_SETTER,			//setter方法
	SIGN_SUBSCRIPT,			//getter形式的下标
	SIGN_SUBSCRIPT_SETTER	//setter形式的下标
} SignatureT`ype;

//loop结构
typedef struct loop{
	int condStartIndex;		//循环中条件的地址
	int bodyStartIndex;		//循环体起始地址
	int scopeDepth;			//循环中若有break，告诉它需要退出的作用域深度
	int exitIndex;			//循环条件不满足时跳出循环体的目标地址
	struct loop* enclosingLoop;	//外层循环
} Loop;

//用于纪录类编译时的信息
typedef struct{
	ObjString* name;		//类名
	SymbolTable fields;		//类属性符号表
	bool inStatic;			//若当前编译静态方法就为真
	IntBuffer instantMethods;	//实例方法
	IntBuffer staticMethods;	//静态方法
	Signature* signature;		//当前正在编译的签名
} ClassBookKeep;


typedef struct compileUnit CompileUnit;
int defineModuleVar(VM* vm, ObjModule* objModule, const char* name, uint32_t length, Value value);

#endif